<template>
	<div id="exception-log">
		<el-form :inline="true" :model="query" size="mini" class="query-box" ref="queryForm">
			<el-form-item prop="requestId"><el-input v-model="query.requestId" placeholder="请求id" style="width: 120px;" clearable></el-input></el-form-item>
			<el-form-item prop="exceptionNames">
				<el-select
					v-model="select_exceptionNames"
					multiple
					collapse-tags
					placeholder="异常名"
					:loading="isLoading"
					clearable
					@focus="getExceptionLogExceptNames"
					style="width: 300px"
				>
					<el-option v-for="(item, index) in exception_list" :label="formatClassName(item)" :key="index" :value="item">
						<el-tooltip class="item" effect="dark" :content="item" placement="right">
							<div class="acenter">{{ formatClassName(item) }}</div>
						</el-tooltip>
					</el-option>
				</el-select>
			</el-form-item>
			<el-form-item><date-time-range-picker v-model="query" ref="dataTimeRangePicker"></date-time-range-picker></el-form-item>
			<el-form-item style="width: 70px;" prop="status">
				<el-select v-model="query.r" placeholder="请求" clearable>
					<el-option label="有" value="y"></el-option>
					<el-option label="无" value="n"></el-option>
				</el-select>
			</el-form-item>
			<el-form-item>
				<el-button type="primary" @click="getData(pager.pageNum, pager.pageSize)">查询</el-button>
				<el-button @click="resetQuery">重置</el-button>
			</el-form-item>
		</el-form>
		<el-table :data="arr" style="width: 100%" border>
			<el-table-column type="expand">
				<template slot-scope="props">
					<el-descriptions title="异常日志详情" class="details" border :column="1" labelClassName="acenter">
						<el-descriptions-item v-if="props.row.requestId" label="请求id">{{ props.row.requestId }}</el-descriptions-item>
						<el-descriptions-item label="message">
							<el-input :value="props.row.message" type="textarea" :autosize="{ minRows: 2, maxRows: 10 }"></el-input>
						</el-descriptions-item>
					</el-descriptions>
				</template>
			</el-table-column>
			<el-table-column type="index" width="70" align="center" label="序号"></el-table-column>
			<el-table-column prop="id" label="id" align="center" width="100"></el-table-column>
			<el-table-column label="请求信息" align="center" width="100">
				<template slot-scope="scope">
					<el-button v-if="scope.row.requestId" size="mini" @click="lookRequest(scope.row.requestId)">查看</el-button>
					<el-tag type="warning" v-else disable-transitions>无</el-tag>
				</template>
			</el-table-column>
			<el-table-column label="异常名" align="center">
				<template slot-scope="scope">
					<el-tooltip v-if="scope.row.name" effect="dark" :content="scope.row.name" placement="top">
						<div class="exceptionName">{{ scope.row.name }}</div>
					</el-tooltip>
					<el-tag type="info" v-else disable-transitions>无</el-tag>
				</template>
			</el-table-column>
			<el-table-column label="message" align="center">
				<template slot-scope="scope">
					<div v-if="scope.row.message" class="short message">{{ scope.row.message }}</div>
					<el-tag type="info" v-else disable-transitions>无</el-tag>
				</template>
			</el-table-column>
			<el-table-column label="时间" width="200" align="center">
				<template slot-scope="scope">
					{{ scope.row.createTime | DF }}
				</template>
			</el-table-column>

			<el-table-column label="操作" width="200" align="center">
				<template slot-scope="scope">
					<el-button @click="showStackTrace(scope.row.id)" size="mini">查看堆栈</el-button>
				</template>
			</el-table-column>
		</el-table>
		<pagination v-model="pager" @change="getData"></pagination>

		<el-dialog title="堆栈信息" :visible.sync="showDialogStackTrace" append-to-body top="20px" width="80%" destroy-on-close>
			<div class="match-braces rainbow-braces">
				<pre>
		  		<code class="language-java">{{ str }}</code>
		  	</pre>
			</div>
		</el-dialog>

		<el-dialog title="请求详情" :visible.sync="showDialogRequestDetail" append-to-body top="20px" width="80%" destroy-on-close>
			<div class="request-detail">
				<el-descriptions title="用户信息" direction="vertical" border>
					<el-descriptions-item label="请求id">{{ requestDetail.requestId }}</el-descriptions-item>
					<el-descriptions-item label="uri">{{ requestDetail.uri }}</el-descriptions-item>
					<el-descriptions-item label="请求方法">
						<el-tag size="small">{{ requestDetail.method }}</el-tag>
					</el-descriptions-item>
					<el-descriptions-item label="ip">{{ requestDetail.ip }}</el-descriptions-item>
					<el-descriptions-item label="ip信息">{{ requestDetail.city }}</el-descriptions-item>
					<el-descriptions-item label="系统">{{ requestDetail.os }}</el-descriptions-item>
					<el-descriptions-item label="浏览器">{{ requestDetail.browser }}</el-descriptions-item>
					<el-descriptions-item label="时间">{{ requestDetail.createTime | DF }}</el-descriptions-item>
					<el-descriptions-item label="耗时">
						<el-tag size="small">{{ requestDetail.time }}ms</el-tag>
					</el-descriptions-item>
					<el-descriptions-item label="handler">{{ requestDetail.handler }}</el-descriptions-item>
					<el-descriptions-item label="参数">{{ requestDetail.param }}</el-descriptions-item>
				</el-descriptions>
			</div>
		</el-dialog>
	</div>
</template>

<script>
import {$get} from '@/puigins/request.js'
import { parseTime } from '@/utils/index.js';
import pagination from '@/components/common/Pagination.vue';
import dateTimeRangePicker from '@/components/common/DateTimeRangePicker.vue';
export default {
	name: 'ExceptionLog',
	created() {
		this.getData(1, this.getDefaultPageSize());
	},
	methods: {
		getData(page, pageSize) {
			this.saveDefaultPageSize(pageSize);
			this.query.exceptionNames = this.select_exceptionNames.join();
			$get('/admin/manage/exceptionLog/getExceptionLog', Object.assign({ page, pageSize }, this.query)).then(res => {
				console.log(res);
				if (res.code == 200) {
					this.arr = res.data.list;
					this.pager = res.data;
				} else {
					console.log(res);
					this.$message.error(res.data);
				}
			});
		},
		showStackTrace(id) {
			$get('/admin/manage/exceptionLog/getExceptionStackTrace',{id}).then(res=>{
				if(res.code==200){
					this.str = '\n' + res.data;
					this.showDialogStackTrace = true;
					this.$nextTick(() => {
						Prism.highlightAll();
					});
				}else{
					this.$msgError(res)
				}
			})
			
		},
		lookRequest(requestId) {
			get("/admin/manage/visitorLog/getVisitLogByRequestId",{requestId}).then(res => {
				if (res.code == 200) {
					this.showDialogRequestDetail = true;
					this.requestDetail = res.data;
					console.log(res);
				} else {
					console.log(res);
					this.$message.error(res.data);
				}
			});
		},
		getExceptionLogExceptNames() {
			if (this.exception_list.length !== 0 || this.isLoading) return;
			this.isLoading = true;
			$get("admin/exceptionLog/getExceptionLogExceptNames").then(res => {
				this.isLoading = false;
				if (res.code == 200) {
					this.exception_list = res.data;
				} else {
					console.log(res);
					this.$message.error(res.data);
				}
			});
		},
		resetQuery() {
			this.$refs['queryForm'].resetFields();
			this.query.startTime = '';
			this.query.endTime = '';
			this.$refs['dataTimeRangePicker'].reset();
			this.select_exceptionNames = [];
			this.getData(this.pager.pageNum, this.pager.pageSize);
		},
		formatClassName(str) {
			return str.substring(str.lastIndexOf('.') + 1);
		},
		getDefaultPageSize() {
			let v = window.localStorage.getItem('logPageSize');
			if (v == null || isNaN(v)) return 8;
			return parseInt(v);
		},
		saveDefaultPageSize(pageSize) {
			window.localStorage.setItem('logPageSize', pageSize);
		}
	},
	data() {
		return {
			arr: [],
			pager: {},
			str: '',
			showDialogStackTrace: false,
			showDialogRequestDetail: false,
			requestDetail: {},
			query: {
				requestId: '',
				startTime: '',
				endTime: '',
				r: '',
				exceptionNames: ''
			},
			isLoading: false,
			exception_list: [],
			select_exceptionNames: []
		};
	},
	filters: {
		DF(t) {
			return parseTime(t);
		}
	},
	components: {
		pagination,
		dateTimeRangePicker
	}
};
</script>

<style lang="scss">
#exception-log {
	width: 100%;

	.short {
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.message,
	.exceptionName {
		white-space: nowrap;
	}
	.el-select__tags {
		overflow: hidden;
		> span {
			display: flex;
		}
	}
}
</style>
